<?php

namespace App\Models;

use App\Http\Controllers\Home\CommonController;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class Orders extends BaseModel
{
    public $timestamps = false;

    protected $table = "orders";

    protected $guarded = [];

    public function getOne($where, $fileds = '*')
    {
        return $this->multiSelect($fileds)->multiWhere($where)->first();
    }

    /**
     * 按条件查询全部数据,根据配置显示条数显示
     */
    public function getList(array $where = [], $fields = '*', $order = '', $pageSize = '')
    {
        if ($pageSize) {
            return $this->multiSelect($fields)->multiWhere($where)->multiOrder($order)->paginate($pageSize);
        } else {
            return $this->multiSelect($fields)->multiWhere($where)->multiOrder($order)->get();
        }
    }

    /**
     * 按条件查询全部数据,根据配置显示条数显示
     */
    public function getOrderCurrencyMemberList(array $where = [], $fields = '*', $order = '', $pageSize = '')
    {
        if ($pageSize) {
            return $this->with('currency')->with('member')->multiSelect($fields)->multiWhere($where)->multiOrder($order)->paginate($pageSize);
        } else {
            return $this->with('currency')->with('member')->multiSelect($fields)->multiWhere($where)->multiOrder($order)->get();
        }
    }

    public function currency()
    {
        return $this->belongsTo('App\Models\Currency', 'currency_id', 'currency_id');
    }

    public function member()
    {
        return $this->belongsTo('App\Models\Member', 'member_id', 'member_id');
    }

    /**
     *插入数据
     */
    public function add($data)
    {
        return $this->_add($data);
    }

    /***
     * @param array $id
     * @param array $data
     * 更新数据
     */
    public function up($where, $data)
    {
        return $this->_updata($where, $data);
    }

    /**
     * @param $id
     * 删除数据
     */
    public function del($where)
    {
        return $this->_del($where);
    }

    function getPageNoList($totalPage, $pageNo, $pageSize)
    {
        $disPageList = 0;//定义最大链接显示数额
        $disPageList = $pageNo + $pageSize - 1;//最大链接显示数额赋值，公式为"当前页数 + 最大链接显示数额 -1"
        //前页面导航页数
        $pageNoList = array();
        //循环显示出当前页面导航页数
        if ($disPageList <= $totalPage) {
            for ($i = $pageNo; $i <= $disPageList; $i++) {
                $pageNoList[] = $i;
            }
        } else {
            if ($totalPage < $pageSize) {
                for ($i = 1; $i <= $totalPage; $i++) {
                    $pageNoList[] = $i;
                }
            } else {
                $start = $totalPage - $pageSize + 1;
                for ($i = $start; $i <= $totalPage; $i++) {
                    $pageNoList[] = $i;
                }
            }
        }
        return $pageNoList;
    }


    //委托记录:Orders表+currency表+member表带分页
    public function getOrderCurrencyMemberListFenye($request)
    {
        $where = [];
        $status = isset($request['status']) ? trim($request['status']) : '';//订单类别 '0是挂单，1是部分成交,2成交， -1撤销'
        $currency_id = isset($request['currency_id']) ? trim($request['currency_id']) : '';    //币种类型
        $email = isset($request['email']) ? trim($request['email']) : '';    //购买人email
        if (!empty($currency_id)) {
            $where['currency_id'] = $currency_id;
        }
        if (!empty($status) || $status === '0') {
            $where['status'] = $status;
        }
        if (!empty($email)) {
            $member_model = new Member();
            $memberinfo = $member_model->getOne(['email' => $email]);
            //dd($memberinfo);
            $where['member_id'] = $memberinfo['member_id'];

        }

        $order['add_time'] = 'desc';
        $rows = $this->getOrderCurrencyMemberList($where, '*', $order, 10);

        if ($rows) {
            $rows = $rows->toArray();
            $rows['pageNoList'] = $this->getPageNoList($rows['last_page'], request('page', 1), 5);
        }
        return $rows;
    }

    /**
     * @param $request
     * @return mixed
     * 撤销订单
     */
    public function cancelOrder($request)
    {
        $orders_id = isset($request['orders_id']) ? trim($request['orders_id']) : '';
        $status = isset($request['status']) ? trim($request['status']) : '';

        if (empty($orders_id)) {
            $data['status'] = 0;
            $data['msg'] = '撤销订单不正确！';
            return $data;
        }
        //dd(123);
        $where['orders_id'] = $orders_id;
        $where['status'] = ['in', array(0, 1)];
        $one_order = $this->getOne($where);     //查询有没有满足要求的订单,0和1才可以撤销
        //dd($one_order);
        if (empty($one_order)) {
            $data['status'] = 0;
            $data['info'] = '撤销订单有误';
            return $data;
        }
        $member_id = $one_order['member_id'];
        $info = $this->cancelOrdersByOrderId($one_order);
        return $info;

    }


    /***
     * @param $list
     *
     * 改变订单状态,撤销订单
     *
     */
    public function cancelOrdersByOrderId($one_order)
    {
        //开启事务
        $this->start();
        try {

            //①把订单表状态改为-1
            $this->setOrdersStatusByOrdersId(-1, $one_order['orders_id']);
            //②返还资金,看是买还是卖
            switch ($one_order['type']) {
                case 'buy':
                    $money = ($one_order['num'] - $one_order['trade_num']) * $one_order['price'];
                    $r[] = $this->setUserMoney($one_order['member_id'], $one_order['currency_trade_id'], $money, 'inc', 'num');
                    $r[] = $this->setUserMoney($one_order['member_id'], $one_order['currency_trade_id'], $money, 'dec', 'forzen_num');
                    break;
                case 'sell':
                    $num = $one_order['num'] - $one_order['trade_num'];
                    $r[] = $this->setUserMoney($one_order['member_id'], $one_order['currency_id'], $num, 'inc', 'num');
                    $r[] = $this->setUserMoney($one_order['member_id'], $one_order['currency_id'], $num, 'dec', 'forzen_num');
                    break;
            }

            $this->commit();
            $info['status'] = 1;
            $info['info'] = '撤销成功';
            return $info;

        } catch (\Exception $e) {
            $this->rollBack();
            //echo $e->getMessage();die();
            $info['status'] = 0;
            $info['info'] = '撤销失败';
            return $info;
        }


    }

    /**
     * 设置订单表状态
     * @param int $status 0 1 2 -1  //'0是挂单，1是部分成交,2成交， -1撤销'
     * @param int $orders_id 订单id
     * @return  boolean
     */
    public function setOrdersStatusByOrdersId($status, $orders_id)
    {

        $where['orders_id'] = $orders_id;
        $data['status'] = $status;
        return $this->up($where, $data);

    }


    /**
     * 设置账户资金
     * @param int $currency_id 币种ID
     * @param int $num 交易数量
     * @param char $inc_dec setDec setInc 是加钱还是减去
     * @param char forzen_num num
     */
    public function setUserMoney($member_id, $currency_id, $num, $inc_dec, $field)
    {
        $inc_dec = strtolower($inc_dec);
        $field = strtolower($field);
        //允许传入的字段
        if (!in_array($field, array('num', 'forzen_num'))) {
            return false;
        }
        //如果是RMB
        if ($currency_id == 0) {
            //修正字段,修改member表
            switch ($field) {
                case 'forzen_num':
                    $field = 'forzen_rmb';
                    break;
                case 'num':
                    $field = 'rmb';
                    break;
            }
            switch ($inc_dec) {
                case 'inc':   //加钱
                    $msg = DB::table('member')->where('member_id', '=', $member_id)->increment($field, $num);
                    break;
                case 'dec':   //减钱
                    $msg = DB::table('member')->where('member_id', '=', $member_id)->decrement($field, $num);
                    break;
                default:
                    return false;
            }
            return $msg;
        } else {
            switch ($inc_dec) {
                //不是rmb则修改currency_user表
                case 'inc':
                    $msg = DB::table('currency_user')->where('member_id', '=', $member_id)->where('currency_id', '=', $currency_id)->increment($field, $num);
                    break;
                case 'dec':
                    $msg = DB::table('currency_user')->where('member_id', '=', $member_id)->where('currency_id', '=', $currency_id)->decrement($field, $num);
                    break;
                default:
                    return false;
            }
            return $msg;
        }


    }


    /*******前台**********/

    /**
     * 去交易
     */
    public function index($request)
    {
        if (empty($request['currency'])) {
            abort(400);
            return;
        }
        $currency_mark = $request['currency'];
        $currencyModel = new Currency();
        $currency = $currencyModel->getOne(['currency_mark' => $currency_mark, 'is_line' => 1]);
        if (empty($currency)) {
            abort(400);
            return;
        }
        $currency['currency_digit_num'] = $currency['currency_digit_num'] ? $currency['currency_digit_num'] : 4;//设置限制位数
        //显示委托记录
        $buy_record = $this->getOrdersByType($currency['currency_id'], 'buy', 10, 'desc');
        $sell_record = $this->getOrdersByType($currency['currency_id'], 'sell', 10, 'asc');

        //格式化手续费
        $currency['currency_sell_fee'] = floatval($currency['currency_sell_fee']);
        $currency['currency_buy_fee'] = floatval($currency['currency_buy_fee']);
        //币种信息
        $tradeModel = new Trade();
        $currency_message = $tradeModel->getCurrencyMessageById($currency['currency_id']);
        $currency_trade = $this->getCurrencynameById($currency['trade_currency_id']);
        //个人账户资产
        $user_currency_money = [];
        $user_orders = [];
        $sell_num = [];
        $buy_num = [];
        if (!empty(session('USER_KEY_ID'))) {
            $user_currency_money['currency']['num'] = $this->getUserMoney($currency['currency_id'], 'num');
            $user_currency_money['currency']['forzen_num'] = $this->getUserMoney($currency['currency_id'], 'forzen_num');
            $user_currency_money['currency_trade']['num'] = $this->getUserMoney($currency['trade_currency_id'], 'num');
            $user_currency_money['currency_trade']['forzen_num'] = $this->getUserMoney($currency['trade_currency_id'], 'forzen_num');
            if ($currency['trade_currency_id'] == 0) {
                $user_currency_money['currency_trade']['num'] = $this->mb('rmb');
                $user_currency_money['currency_trade']['forzen_num'] = $this->mb('forzen_rmb');

            }
            //个人挂单记录
            $user_orders = $this->getOrdersByUser(5, $currency['currency_id']);
            //最大可买
            if (!empty($sell_record)) {
                $buy_num = sprintf('%.4f', $user_currency_money['currency_trade']['num'] / $sell_record[0]['price']);
            } else {
                $buy_num = 0;
            }
            //最大可卖
            $sell_num = sprintf('%.4f', $user_currency_money['currency']['num']);
        }

        //成交记录
        $trade = $this->getOrdersByStatus(2, 20, $currency['currency_id']);

        return [$buy_record, $sell_record, $currency_message, $currency_trade, $user_currency_money, $user_orders, $buy_num, $sell_num, $currency, $trade];
    }


    //获取挂单记录
    public function getOrders($request)
    {
        switch ($request['type']) {
            case 'buy':
                return ($this->getOrdersByType($request['currency_id'], 'buy', 10, 'desc'));
                break;
            case 'sell':
                return ($this->getOrdersByType($request['currency_id'], 'sell', 10, 'asc'));
                break;
        }
    }

    //获取k线
    public function getOrdersKline($request)
    {
        if (empty($request['currency'])) {
            return;
        }
        $currency_id = $request['currency'];
        //K线
        $char = !empty($request['time']) ? $request['time'] : 'kline_1h';
        switch ($char) {
            case 'kline_5m':
                $time = 5;
                break;
            case 'kline_15m':
                $time = 15;
                break;
            case 'kline_30m':
                $time = 30;
                break;
            case 'kline_1h':
                $time = 60;
                break;
            case 'kline_8h':
                $time = 480;
                break;
            case 'kline_1d':
                $time = 24 * 60;
                break;
            default:
                $time = 60;
        }
        $trade = new Trade();
        $data[$char] = $trade->getKline($time, $currency_id);
        return $data;
    }


    /**
     * 返回指定数量排序的挂单记录
     * @param char $type buy sell
     * @param int $num 数量
     * @param char $order 排序 desc asc
     */
    protected function getOrdersByType($currencyid, $type, $num, $order)
    {
        $where['type'] = $type;
        $where['status'] = ['in', [0, 1]];
        $where['currency_id'] = $currencyid;
        $res = $this->multiSelect('sum(num) as num,sum(trade_num) as trade_num,price,type,status')->multiWhere($where)->groupBy('price')->multiOrder(['price' => $order, 'add_time' => 'asc'])->take($num)->get()->toArray();
        foreach ($res as $k => $v) {
            $res[$k]['bili'] = 100 - ($v['trade_num'] / $v['num'] * 100);
        }
        if ($type == 'sell') {
            $res = array_reverse($res);
        }
        return $res;
    }

    /**
     * 实例化币种
     * @param unknown $currency_id 币种id
     * @return unknown
     */
    public function getCurrencynameById($currency_id)
    {
        if ($currency_id == 0) {
            return array('currency_name' => '人民币', 'currency_mark' => 'CNY', 'currency_buy_fee' => 0, 'currency_sell_fee' => 0);
        }
        $currency = new Currency();
        $where['currency_id'] = $currency_id;
        return $currency->getOne($where, 'currency_name,currency_mark,currency_buy_fee,currency_sell_fee');
    }


    /**
     *  获取当前登陆账号指定币种的金额
     * @param int $currency_id 币种ID
     * @param char $field num  forzen_num
     * @return array 当前登陆人账号信息
     */
    public function getUserMoney($currency_id, $field)
    {
        if (empty($currency_id)) {
            switch ($field) {
                case 'num':
                    $field = 'rmb';
                    break;
                case 'forzen_num':
                    $field = 'forzen_rmb';
                    break;
                default:
                    $field = 'rmb';
            }
            $memberModel = new Member();
            $member = $memberModel->getOne(['member_id' => session('USER_KEY_ID')]);
            $memberAll = $member[$field];
        } else {
            $currencyUser = new CurrencyUser();
            $currencyUserInfo = $currencyUser->getOne(['member_id' => session('USER_KEY_ID'), 'currency_id' => $currency_id]);
        }
        return isset($memberAll) ? $memberAll : $currencyUserInfo[$field];
    }

    public function mb($field)
    {
        $memberModel = new Member();
        $member = $memberModel->getOne(['member_id' => session('USER_KEY_ID')]);
        return $member[$field];
    }

    /**
     * 获取指定数量个人挂单记录
     * @param int $num 数量
     */
    protected function getOrdersByUser($num, $currency_id)
    {
        $where['member_id'] = session('USER_KEY_ID');
        $where['status'] = ['in', [0, 1]];
        $where['currency_id'] = $currency_id;
        return $this->multiWhere($where)->orderBy('add_time', 'desc')->take($num)->get();

    }

    /**
     * 返回指定状态的挂单记录
     * @param int $status -1 0 1 2
     * @param int $num 数量
     * @param int $currency_id 币种id
     */
    protected function getOrdersByStatus($status, $num, $currency_id)
    {
        $where['currency_id'] = $currency_id;
        $where['status'] = $status;
        return $this->multiWhere($where)->take($num)->orderBy('trade_time', 'desc')->get();
    }

    //交易大厅
    public function getCurrencyTrade()
    {
        $trad = new Trade();
        $currencyModel = new Currency();
        $pageSize = 10;
        $currency = $currencyModel->getList(['is_line' => 1], '*', ['sort' => 'desc'], $pageSize)->toArray();
        if ($currency['data']) {
            foreach ($currency['data'] as $k => $v) {
                $list = $trad->getCurrencyMessageById($v['currency_id']);
                $currency['data'][$k] = array_merge($list, $currency['data'][$k]);
                $list['new_price'] ? $list['new_price'] : 0;
                $currency['data'][$k]['currency_all_money'] = floatval($v['currency_all_num']) * $list['new_price'];
            }
            $currency['pageNoList'] = getPageNoList($currency['last_page'], request('page', 1), 5);
        }
        return $currency;
    }


    /**
     * 返回用户第一条未成交的挂单
     * @param int $memberId 用户id
     * @param int $currencyId 币种id
     * @return array 挂单记录
     */
    public function getFirstOrdersByMember($memberId,$type,$currencyId){
        $where['member_id'] = $memberId;
        $where['currency_id'] = $currencyId;
        $where['type'] = $type;
        $where['status'] = array('in',array(0,1));
        return $this->multiWhere($where)->multiOrder(['add_time'=>'desc'])->first();
    }


    /**
     * 返回一条挂单记录
     * @param int $currencyId 币种id
     * @param float $price 交易价格
     * @return array 挂单记录
     */
    public function getOneOrders($type,$currencyId,$price){
        switch ($type){
            case 'buy':
                $gl = '>=';
                $order = 'price desc,add_time asc';
                break;
            case 'sell':
                $gl = '<=';
                $order = 'price asc,add_time asc';
                break;
        }
        $where['currency_id'] = $currencyId;
        $where['type'] = $type;
        $where['price'] = array($gl,$price);
        $where['status'] = array('in',array(0,1));
        $res = $this->multiWhere($where)->multiOrder(['add_time'=>'desc'])->multiOrder($order)->first();
        return $res;
    }

    public function entrust($where)
    {
        $list = $this->multiWhere($where)->get();
        return $list;
    }


    public function getOrderListWithCurrency(array $where, $fields = '*', array $order = [], $pageSize = 10, $pageLength = 5)
    {
        $rows = $this->multiSelect($fields)->with('currency')->withCertain('currency',['currency_id','currency_name'])->multiWhere($where)->multiOrder($order)->paginate($pageSize);
        if ($rows) {
            $rows = $rows->toArray();
            $rows['pageNoList'] = $this->getPageNoList($rows['last_page'], request('page', 1), $pageLength);
        }
        return $rows;
    }


    public function getOneOrdersByMemberAndOrderId($member_id,$order_id,$status=array(0,1,2,-1)){
        $where['member_id']=$member_id;
        $where['orders_id']=$order_id;
        $where['status']=array('in',$status);
        return $this->multiWhere($where)->first();
    }



}
